home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume91
/
utilitys
/
sman_1_1
/
part01
/
src
/
sman.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-29
|
6KB
|
371 lines
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <libraries/dos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/sregexp_protos.h>
#include <libraries/sregexpbase.h>
#include "sman_defs.h"
Prototype long findman(char *, char *, char *, int);
Prototype long searchpath(char *, char *, char *, int);
Prototype void usage(void);
Prototype long okfile(char *, char *, char);
Prototype void putline(char *);
Prototype void leave(char *, int);
Prototype char * expandpath(char *, char *);
Prototype int spathbrk(void);
const char memory[] = "sman: Unable to allocate memory.\n";
int
main(ac,av)
int ac;
char *av[];
{
char *com,*path = NULL,file[MAXPATH],*viewer = NULL;
long line;
do {
if (--ac < 1 || **++av != '-')
break;
switch (*(*av+1)) {
case ('p') :
case ('P') :
if (!*(path = *av + 2)) {
ac--;
path = *(++av);
}
break;
case ('v') :
case ('V') :
if (!*(viewer = *av + 2)) {
ac--;
viewer = *(++av);
}
break;
default :
usage();
}
} while (1);
if (ac < 1)
usage();
if (!path)
if (!(path = getenv("SmanPath"))) {
putline("Environment Variable SmanPath not defined.\n");
return 1;
}
if (!viewer)
viewer = getenv("SmanViewer");
while (ac >= 1) {
if ((line = findman(av[0],path,file,MAXPATH)) != NOT_FOUND) {
if (viewer) {
if (!(com = malloc(strlen(viewer)+strlen(file)+2))) {
putline(memory);
return 5;
}
strcpy(com,viewer);
strcat(com," ");
strcat(com,file);
} else {
char f = FALSE;
int i,mod;
if (!(com = malloc(strlen(file)+17))) {
putline(memory);
return 5;
}
strcpy(com,"sless -");
if (line > 0)
com[7] = 'l';
else {
com[7] = 'c';
line = -line;
}
for (i = 8, mod = 10000000; mod != 0; mod /= 10) {
com[i] = line / mod + '0';
if (com[i] != '0' || f || mod == 1) {
f = TRUE;
i++;
}
line %= mod;
}
com[i++] = ' ';
strcpy(com+i,file);
}
system(com);
}
ac--;
av++;
}
return 0;
}
long
findman(tar,p,file,len)
char *tar,*p,*file;
int len;
{
char *h,q;
long line;
do {
h = p;
while (*p != ';' && *p) p++;
q = *p;
*p = 0;
line = searchpath(h,tar,file,len);
*p++ = q;
if (line != NOT_FOUND)
return line;
} while (q);
putline("No manual entry found for '");
putline(tar);
putline("'.\n");
return NOT_FOUND;
}
/* This has to be global to free it on a break... */
struct SpathInfo *spath = NULL;
long
searchpath(p,tar,file,len)
char *p,*tar,*file;
int len;
{
char *e;
long line,test;
if (!(e = expandpath(p + (*p == ADOC || *p == DREF ? 1 : 0),tar)))
return NOT_FOUND;
spath = AnchorPath("",e);
free(e);
if (!spath) {
putline("Illegal Path rule '");
putline(p);
putline("'\n");
return NOT_FOUND;
}
onbreak(&spathbrk);
line = NOT_FOUND;
do {
while ((test = NextFile(spath,file,len,SP_FILES_ONLY)) > 0) {
line = okfile(file,tar,*p);
if (line != NOT_FOUND)
break;
}
if (test == SPE_SIGBREAK) {
chkabort();
SetSignal(0,SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F);
test = 0;
}
} while (line == NOT_FOUND && test >= 0);
onbreak(NULL);
FreeSpathInfo(spath);
spath = NULL;
return line;
}
int
spathbrk()
{
if (spath)
FreeSpathInfo(spath);
return 1;
}
long
okfile(file,tar,ftype)
char *file,*tar,ftype;
{
FILE *fp;
char buff[200],*m,*n;
int line,len;
struct SregExp *spat;
if (ftype != ADOC && ftype != DREF)
return 0;
if (!(fp = fopen(file,"r")))
return NOT_FOUND;
if (ftype == ADOC) {
line = -1;
do {
if (fgets(buff,199,fp) != buff) {
fclose(fp);
return NOT_FOUND;
}
line++;
} while (*buff == '\n');
if (strnicmp("TABLE OF CONTENTS",buff,17)) {
fclose(fp);
return NOT_FOUND;
}
strcpy(buff,"#?/(");
strcat(buff,tar);
strcat(buff,")\n");
if (!(spat = ParseSregExp(buff))) {
fclose(fp);
return NOT_FOUND;
}
while (fgets(buff,199,fp) == buff) {
line++;
if (*buff == 12) {
FreeSregExp(spat);
fclose(fp);
return NOT_FOUND;
}
if (MatchSregExp(buff,spat,TRUE))
goto agotit;
}
FreeSregExp(spat);
fclose(fp);
return NOT_FOUND;
agotit:
FreeSregExp(spat);
len = strlen(buff);
buff[len-1] = 0;
if (!(m = malloc(len))) {
fclose(fp);
leave(memory,5);
}
strcpy(m,buff);
while (fgets(buff,199,fp) == buff) {
line++;
if (strncmp(m,buff,len - 1) == 0) {
free(m);
fclose(fp);
return line;
}
}
free(m);
fclose(fp);
return NOT_FOUND;
} else {
len = strlen(tar);
while (fgets(buff,199,fp) == buff) {
if (strncmp(tar,buff,len) == 0 && isspace(buff[len])) {
fclose(fp);
goto dgotit;
}
}
fclose(fp);
return NOT_FOUND;
dgotit:
m = buff;
for (len = 0; len < 2; len++) {
while (!isspace(*m++)) ;
while (isspace(*m)) m++;
}
n = m;
while (*n != ':' && *n != '/' && !isspace(*n)) n++;
if (*n == ':')
n = file;
else {
n = file + strlen(file);
while (*(n-1) != '/' && *(n-1) != ':' && n != file) n--;
}
while (!isspace(*m))
*n++ = *m++;
*n = 0;
while (isspace(*m)) m++;
if (*m++ != '@' || *m++ != '@')
return 0;
line = 0;
while (!isspace(*m))
line = line*10 - *m++ + '0';
return line;
}
}
char *
expandpath(p,tar)
char *p,*tar;
{
int num = 0;
char *q,*r,*t;
for (q = p; *q; q++) {
if (*q == '\'' && *(q+1) == '&')
q++;
else if (*q == '&')
num++;
}
if (!(q = malloc(strlen(p) + num*(strlen(tar)+1) + 1))) {
putline(memory);
return NULL;
}
for (r = q; *p; p++) {
if (*p == '&') {
*r++ = '(';
for (t = tar; *t; t++)
*r++ = *t;
*r++ = ')';
} else {
if (*p == '\'' && *(p+1) == '&')
p++;
*r++ = *p;
}
}
*r = 0;
return q;
}
void
usage()
{
putline("sman V"\
VERSION\
", "
__DATE__\
", (c)Copyright 1991 by Jon Spencer.\n");
putline("Usage: Sman [-pSearch pattern] [-vViewer] target [target...]\n");
exit(2);
}
void
putline(p)
char *p;
{
Write(Output(),p,strlen(p));
}
void
leave(p,x)
char *p;
int x;
{
putline(p);
exit(x);
}
int printf(f, ...)
const char *f;
{
char buff[100];
va_list va;
va_start(va,f);
vsprintf(buff,f,va);
va_end(va);
Write(Output(),buff,strlen(buff));
}